﻿using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MugenInjection.Infrastructure;
using MugenInjection.Parameters;
using TestModels.Class;
using System.Reflection;
using System.Linq;
using Should;

namespace MugenInjectionTest.Parameters
{
    [TestClass]
    public class MethodParameterTest
    {

        [TestMethod]
        public void CanResolveNamedTest()
        {
#if NETFX_CORE
            var falseMethod = typeof(ParameterTestModel).GetTypeInfo().DeclaredMethods.First(c => c.Name == "Method");
            var trueMethod = typeof(ParameterTestModel).GetTypeInfo().DeclaredMethods.First(c => c.Name == "Method1");
#else
            var falseMethod = typeof(ParameterTestModel).GetMethod("Method");
            var trueMethod = typeof(ParameterTestModel).GetMethod("Method1");
#endif

            var parameter = new MethodParameter("Method1", "param1", string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method1", "param1", context => string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method1", "param1", typeof(string), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method1", "param1", context => string.Empty, typeof(string));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method3", "param1", typeof(string), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method3", "param1", context => string.Empty, typeof(string));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", "param1", typeof(bool), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", "param1", context => string.Empty, typeof(bool));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", "param1f", typeof(bool), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", "param1f", context => string.Empty, typeof(bool));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();
        }


        [TestMethod]
        public void CanResolveIndexTest()
        {
#if NETFX_CORE
            var falseMethod = typeof(ParameterTestModel).GetTypeInfo().DeclaredMethods.First(c => c.Name == "Method");
            var trueMethod = typeof(ParameterTestModel).GetTypeInfo().DeclaredMethods.First(c => c.Name == "Method1");
#else
            var falseMethod = typeof(ParameterTestModel).GetMethod("Method");
            var trueMethod = typeof(ParameterTestModel).GetMethod("Method1");
#endif

            var parameter = new MethodParameter("Method1", 0, string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method1", 0, context => string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method1", 0, typeof(string), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method1", 0, context => string.Empty, typeof(string));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeTrue();

            parameter = new MethodParameter("Method3", 0, typeof(string), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method3", 0, context => string.Empty, typeof(string));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", 0, typeof(bool), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", 0, context => string.Empty, typeof(bool));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", 1, typeof(bool), string.Empty);
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();

            parameter = new MethodParameter("Method1", 1, context => string.Empty, typeof(bool));
            parameter.CanResolve(falseMethod, null).ShouldBeFalse();
            parameter.CanResolve(trueMethod, trueMethod.GetParameters()[0]).ShouldBeFalse();
        }

        [TestMethod]
        public void GetValueTest()
        {
            var value = new object();
            var value1 = new object();

            var parameter = new MethodParameter("Method1", "param1", value);
            parameter.GetValue(new ParameterContext(null, null)).ShouldEqual(value);

            parameter = new MethodParameter("Method1", "param1", context => value1);
            parameter.GetValue(new ParameterContext(null, null)).ShouldEqual(value1);
        }
    }
}